﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XbsWebAPI.Application;
using XbsWebAPI.Application.SystemAdmin;
using XbsWebAPI.Application.SystemAdmin.Dtos;
using XbsWebAPI.Core.Tools;
using XbsWebAPI.EntityFrameworkCore.Entities;
using XbsWebAPI.EntityFrameworkCore.Entities.SystemAdmin;
using Newtonsoft.Json;

namespace XbsWebAPI.Core.Repositories
{
    /// <summary>
    /// 菜单 应用服务层
    /// </summary>
    public class SystemRoleAppService : ISystemRoleAppService
    {
        private readonly ISystemRoleRepository _systemRoleRepository;
        private readonly IMenuRepository _menuRepository;
        private readonly ILogger<SystemRoleAppService> _logger;
        private readonly IMapper _mapper;

        public SystemRoleAppService(ISystemRoleRepository systemroleRepository,ILogger<SystemRoleAppService> logger,IMapper mapper,IMenuRepository menuRepository)
        {
            _systemRoleRepository = systemroleRepository;
            _logger = logger;
            _mapper = mapper;
            _menuRepository = menuRepository;
        }

        public Task<ResultDto<string>> CreateSystemRoleAsync(CreateSystemRoleDto model)
        {
            var result = new ResultDto<string>();
            var menuTreeList = MenusTreeList();
            try
            {
                var entity = _mapper.Map<SystemRole>(model);
                //选择的树
                //var menuTrees = menusHanlder(model.SelectedMenus);
                if(model.MenuIds != null && model.MenuIds.Any())
                {
                    entity.MenuStrJson = JsonConvert.SerializeObject(model.MenuIds);
                }
                
                _systemRoleRepository.CreateAsync(entity);
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Code = -1;
                result.Message = e.Message;
                _logger.LogError("CreateSystemRoleAsync:" + e.Message);
                return Task.FromResult(result);
            }

            return Task.FromResult(result);
        }

        public List<MenuTreeDto> CurrentMenuTreeList(List<Guid> menuIds)
        {
            if(menuIds == null || menuIds.Count == 0)
                return new List<MenuTreeDto>();

            //所有的Id 去重
            var allMenuIds = new List<Guid?>();
            var allMenus = new List<Menu>();
            //根据Id列表查询出所有的菜单
            var selectedMenus = new List<Menu>();
            foreach (var menuId in menuIds)
            {
                var menu = _menuRepository.QueryById(menuId);
                if(menu != null)
                {
                    selectedMenus.Add(menu);
                }
            }
            var menuTreeDtos = new List<MenuTreeDto>();
            

            var parentIds = selectedMenus.Where(a => a.ParentId != null).Select(a => a.ParentId).Distinct().ToList();
            var chilrenIds = selectedMenus.Where(a => a.ChildId != null).Select(a => a.ChildId).Distinct().ToList();
            var butonIds = selectedMenus.Where(a => a.ButtonId != null).Select(a => a.ButtonId).Distinct().ToList();
            allMenuIds.AddRange(parentIds);
            allMenuIds.AddRange(chilrenIds);
            allMenuIds.AddRange(butonIds);

            foreach (var menuId in allMenuIds)
            {
                var menu = _menuRepository.QueryById(menuId.Value);
                allMenus.Add(menu);
            }

            //组装一级菜单
            foreach (var parentId in parentIds)
            {
                var menuTreesDto = new MenuTreeDto();
                var pMenu = allMenus.Find(a => a.Id == parentId);
                var pMenuTree = new MenuTreeDto()
                {
                    MenuType = MenuType.Parent,
                    Id = pMenu.Id,
                    Name = pMenu.Name,
                    Sort = pMenu.Sort,
                    Path = pMenu.Path,
                    Icon = pMenu.Icon,
                };
                menuTreeDtos.Add(pMenuTree);
            }



            //组装二级菜单
            foreach (var childId in chilrenIds)
            {
                var cMenu = allMenus.Find(a => a.Id == childId);
                var pMenuTreeDtos = menuTreeDtos.Find(a => a.Id == cMenu.PId);
                var cMenuTree = new ChildMenuTreeDto
                {
                    MenuType = MenuType.Child,
                    Id = cMenu.Id,
                    Name = cMenu.Name,
                    Sort = cMenu.Sort,
                    PId = cMenu.PId,
                    PName = cMenu.PName,
                    Icon = cMenu.Icon,
                    Path = cMenu.Path,
                };
                //组装三级菜单
                foreach (var buttonId in butonIds)
                {
                    var bMenu = allMenus.Find(a => a.Id == buttonId);
                    if (bMenu.PId == cMenu.Id)
                    {
                        cMenuTree.ButtonMenus.Add(new ButtonMenuTreeDto
                        {
                            MenuType = MenuType.Button,
                            Id = bMenu.Id,
                            PId = bMenu.PId,
                            PName = bMenu.PName,
                            Identifying = bMenu.Identifying,
                        });
                    }
                }

                pMenuTreeDtos.ChilrenMenus.Add(cMenuTree);
            }



            return menuTreeDtos;

            //按MenuTreesDto组装
        }



        public ResultDto<GetSystemRoleDto> GetSystemRoleById(Guid id)
        {
            var result = new ResultDto<GetSystemRoleDto>();

            try
            {

                var model = _systemRoleRepository.QueryById(id);
                var entity = _mapper.Map<GetSystemRoleDto>(model);
                entity.AllMenus = MenusTreeList();

                var menuIds = JsonConvert.DeserializeObject<List<Guid>>(model.MenuStrJson);
                entity.SelectedMenus = CurrentMenuTreeList(menuIds);
                result.Result = entity;
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Message = e.Message;
                result.Code = -1;
                _logger.LogError("GetSystemRoleById:" + e.Message);
                return result;
            }

            return result;
        }

        public ResultDto<List<ListSystemRoleDto>> GetSystemRoles()
        {
            var result = new ResultDto<List<ListSystemRoleDto>>();

            try
            {
                var model = _systemRoleRepository.AsQueryable().ToList();
                var entity = _mapper.Map<List<ListSystemRoleDto>>(model);
                foreach (var item in entity)
                {
                    var role = model.Find(a => a.Id == item.Id);
                    if(role != null && !String.IsNullOrWhiteSpace(role.MenuStrJson))
                    {
                        item.MenuIds = JsonConvert.DeserializeObject<List<Guid>>(role.MenuStrJson);
                    }
                }
                result.Result = entity;
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Message = e.Message;
                result.Code = -1;
                _logger.LogError("GetSystemRoles:" + e.Message);
                return result;
            }

            return result;
        }

        public Task<ResultDto<string>> RemoveRoleByIdAsync(Guid id)
        {
            var result = new ResultDto<string>();

            try
            {
                var model = _systemRoleRepository.DeleteAsync(id);
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Message = e.Message;
                result.Code = -1;
                _logger.LogError("RemoveRoleByIdAsync:" + e.Message);
                return Task.FromResult(result);
            }

            return Task.FromResult(result);
        }

        private List<MenuTreeDto> MenusTreeList()
        {
            var listMenus = new List<MenuTreeDto>();
            var menus = _menuRepository.AsQueryable().ToList();
            //一级菜单
            var pMenus = menus.Where(a => a.PId == null || a.PId == Guid.Empty).OrderBy(a => a.Sort).ToList();
            foreach (var pMenu in pMenus)
            {
                var menuTree = new MenuTreeDto()
                {
                    Id = pMenu.Id,
                    Name = pMenu.Name,
                    Sort = pMenu.Sort,
                    MenuType = pMenu.MenuType,
                    Icon = pMenu.Icon,
                    Path = pMenu.Path
                };

                var childrenTreeMenus = new List<ChildMenuTreeDto>();
                var childrenMenus = menus.Where(a => a.PId == pMenu.Id).OrderBy(a => a.Sort).ToList();
                foreach (var child in childrenMenus)
                {
                    var chilrenMenu = new ChildMenuTreeDto()
                    {
                        Id = child.Id,
                        Name = child.Name,
                        PName = child.PName,
                        PId = child.PId,
                        Sort = child.Sort,
                        MenuType = child.MenuType,
                        Icon = child.Icon,
                        Path = child.Path
                    };

                    chilrenMenu.ButtonMenus = new List<ButtonMenuTreeDto>();
                    var buttons = _menuRepository.Query(a => a.MenuType == MenuType.Button && a.PId == chilrenMenu.Id).ToList();
                    foreach (var button in buttons)
                    {
                        var buttonMenu = new ButtonMenuTreeDto()
                        {
                            Id = button.Id,
                            PName = chilrenMenu.Name,
                            PId = button.PId,
                            Identifying = button.Identifying,
                            MenuType = button.MenuType
                        };
                        chilrenMenu.ButtonMenus.Add(buttonMenu);
                    }


                    menuTree.ChilrenMenus.Add(chilrenMenu);
                }
                listMenus.Add(menuTree);
            }

            return listMenus;
        }

        public ResultDto<List<MenuTreeDto>> ShowMenusTree()
        {
            var result = new ResultDto<List<MenuTreeDto>>();

            try
            {
                result.Result = MenusTreeList();
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Code = -1;
                result.Message = e.Message;
                _logger.LogError("ShowMenusTree:" + e.Message);
                return result;
            }

            return result;
        }

        public Task<ResultDto<string>> UpdateSystemRoleAsync(EditSystemRoleDto model)
        {
            var result = new ResultDto<string>();
            var menuTreeList = MenusTreeList();
            try
            {
                var entity = _mapper.Map<SystemRole>(model);
                //选择的树
                if (model.MenuIds != null && model.MenuIds.Any())
                {
                    entity.MenuStrJson = JsonConvert.SerializeObject(model.MenuIds);
                }
                //entity.MenuStrJson = JsonConvert.SerializeObject(model.MenuIds);
                _systemRoleRepository.UpdateAsync(entity);
                result.Message = "操作成功";
            }
            catch (Exception e)
            {
                result.Code = -1;
                result.Message = e.Message;
                _logger.LogError("UpdateSystemRoleAsync:" + e.Message);
                return Task.FromResult(result);
            }

            return Task.FromResult(result);
        }
    }
}
